<?php
class IndexAction extends Action {
    public function index(){
        $get = file_get_contents("php://input","r");
        $data="[".date("Y-m-d H:i:s")."]".$get;
        file_put_contents("Public/data.txt", $data."\r\n", FILE_APPEND);
        //$data = file_get_contents($getdata);
        $xml = (array)simplexml_load_string($get,'SimpleXMLElement', LIBXML_NOCDATA);
        $paysign = $xml['sign'];
        unset($xml['sign']);
         if($paysign != $this->wxpaySign($xml)){//验证微信返回的签名
             file_put_contents("Public/data.txt", $data."\r\n", FILE_APPEND);
             exit;
         }
         
        $order = M('UserOrder')->where("order_num='{$xml['out_trade_no']}'")->find();
        //echo M('UserOrder')->getLastSql();
        $xml['paytype'] = $order['paytype'];
        switch ($xml['paytype']) {
            case 1:
                $callback = $this->recordorder($xml);
                break;
            case 2:
                $callback = $this->suborder($xml);
                break;
            case 3:
                $callback = $this->packageorder($xml);
                break;
            case 4:
                $callback = $this->discussorder($xml);
                break;
            case 5:
                $callback = $this->eventorder($xml);
                break;
            case 6:
                $callback = $this->pointsorder($xml);
                break;
        }

        if($callback['status']==1){
            return $this->recevieSuccess();
        }else{
            $data = "[".date("Y-m-d H:i:s")."]".$callback['msg'];
            file_put_contents("Public/error.txt", $data."\r\n", FILE_APPEND);
            return $this->recevieSuccess();
        }
    	
	}

    private function recordorder($xml){//1单个
        $condition['order_num']=$xml['out_trade_no'];
        $condition['openid']=$xml['openid'];
        $condition['paytime']=array('eq','');
        $data['transaction_id']=$xml['transaction_id'];
        $data['status']=2;//支付成功;
        $data['paytime']=time();
        $saveorder = M('UserOrder')->where($condition)->save($data);
        $savedetail = M('UserOrderDetail')->where("order_num='{$xml['out_trade_no']}'")->save(array("transaction_id"=>$xml['transaction_id']));
        if($saveorder && $savedetail){
            $expert = D('MedicalView')->where("order_num='{$xml['out_trade_no']}'")->find();
            $addtime = time();
            $token = md5($xml['openid']."|".$expert['item_id']);
            $sql = "INSERT INTO `box_user_records`(`openid`, `rec_id`, `expert_id`, `token`, `addtime`) 
                    VALUES ('{$xml['openid']}',{$expert['item_id']},{$expert['user_id']},'{$token}',{$addtime})
                    ON DUPLICATE KEY UPDATE `addtime`={$addtime}";
            M()->query($sql);
            if(1==mysql_affected_rows()){
                $addpoints = $this->userpoints(100,$xml['openid'],1,$xml['cash_fee']/100,1,$xml['out_trade_no']);//$type,$openid,$add,$points=0,$is_frozen,$order_num=0
                if(!$addpoints){
                     return array("status"=>0,"msg"=>"增加金豆错误");
                }
            }
            return array("status"=>1);
        }else{
            return array("status"=>0,"msg"=>D('MedicalView')->getLastSql());
        }

    }

    private function suborder($xml){//2订阅
        $condition['order_num']=$xml['out_trade_no'];
        $condition['openid']=$xml['openid'];
        $condition['paytime']=array('eq','');
        $data['transaction_id']=$xml['transaction_id'];
        $data['status']=2;//支付成功;
        $data['paytime']=time();
        $saveorder = M('UserOrder')->where($condition)->save($data);
        $savedetail = M('UserOrderDetail')->where("order_num='{$xml['out_trade_no']}'")->save(array("transaction_id"=>$xml['transaction_id']));
        if($saveorder && $savedetail){
            //$addpoints = $this->userpoints(100,$xml['openid'],1,$xml['cash_fee']/100,2,$xml['out_trade_no']);//$type,$openid,$add,$points=0,$is_frozen,$order_num=0
            return array("status"=>1);
        }else{
            return array("status"=>0,"msg"=>M('UserOrder')->getLastSql());
        }
    }

    private function packageorder($xml){//3打包
        $condition['order_num']=$xml['out_trade_no'];
        $condition['openid']=$xml['openid'];
        $condition['paytime']=array('eq','');
        $data['transaction_id']=$xml['transaction_id'];
        $data['status']=2;//支付成功;
        $data['paytime']=time();
        $saveorder = M('UserOrder')->where($condition)->save($data);
        $savedetail = M('UserOrderDetail')->where("order_num='{$xml['out_trade_no']}'")->save(array("transaction_id"=>$xml['transaction_id']));
        if($saveorder && $savedetail){
            $addpoints = $this->userpoints(100,$xml['openid'],1,$xml['cash_fee']/100,1,$xml['out_trade_no']);//$type,$openid,$add,$points=0,$is_frozen,$order_num=0
            $expert = D('PackageView')->where("order_num='{$xml['out_trade_no']}'")->find();
            $d = new DateTime($expert['packageend']);
            $d->modify( '+1 day' );
            $time = $d->format( 'Y-m-d' );
            $recoder['pubtime']=array("lt",strtotime($time));//小于下一天的0点
            $recoder['user_id']=$expert['item_id'];
            $recoder['pubtype']=2;//已经发布的
            $recoder['cashtype']=2;//收费的
            $list = M('MedicalRecords')->field('id')->where($recoder)->select();//获取该专家截至日期前的所有简历
            foreach ($list as $key => $value) {
                $addtime = time();
                $token = md5($xml['openid']."|".$value['id']);
                $sql = "INSERT INTO `box_user_records`(`openid`, `rec_id`, `expert_id`, `token`, `addtime`) 
                        VALUES ('{$xml['openid']}',{$value['id']},{$expert['item_id']},'{$token}',{$addtime})
                        ON DUPLICATE KEY UPDATE `addtime`={$addtime}";
                M()->query($sql);
                if(!mysql_affected_rows()){
                    return array("status"=>0,"msg"=>M('UserOrder')->getLastSql()); 
               }
            }
            return array("status"=>1); 
        }else{
           return array("status"=>0,"msg"=>M('UserOrder')->getLastSql()); 
        }
               
    }

    private function discussorder($xml){//4邀请
        $condition['order_num']=$xml['out_trade_no'];
        $condition['openid']=$xml['openid'];
        $condition['paytime']=array('eq','');
        $data['transaction_id']=$xml['transaction_id'];
        $data['status']=2;//支付成功;
        $data['paytime']=time();
        $saveorder = M('UserOrder')->where($condition)->save($data);
        $savedetail = M('UserOrderDetail')->where("order_num='{$xml['out_trade_no']}'")->save(array("transaction_id"=>$xml['transaction_id']));
        if($saveorder && $savedetail){
            $addpoints = $this->userpoints(90,$xml['openid'],1,$xml['cash_fee']/100,2,$xml['out_trade_no']);//$type,$openid,$add,$points=0,$is_frozen,$order_num=0//冻结金豆
            //获取专家ID和病例ID
            $list = M('UserOrderDetail')->where("order_num='{$xml['out_trade_no']}'")->select();
            foreach ($list as $key => $value) {
                $record['rec_id']=$value['rec_id'];
                $record['user_id']=$value['item_id'];
                $record['pubtype']=$value['pubtype'];
                $record['cashtype']=3;//邀请中
                $record['addtime']=time();
                $record['openid']=$xml['openid'];//付费人的openid
                $record['order_num']=$xml['out_trade_no'];
                $record['content']='';//占坑没内容
                $record['price']=$xml['cash_fee']/100;//分转元
                $add = M('MedicalRecordsDiscuss')->add($record);
                if(!$add){
                    return array("status"=>0,"msg"=>M('MedicalRecordsDiscuss')->getLastSql()); 
                }
            }
            return array("status"=>1); 
        }else{
            return array("status"=>0,"msg"=>M('UserOrder')->getLastSql()); 
        }
    }

    private function eventorder($xml){//5活动
        $condition['order_num']=$xml['out_trade_no'];
        $condition['openid']=$xml['openid'];
        $condition['paytime']=array('eq','');
        $data['transaction_id']=$xml['transaction_id'];
        $data['status']=2;//支付成功;
        $data['paytime']=time();
        $saveorder = M('UserOrder')->where($condition)->save($data);
        $savedetail = M('UserOrderDetail')->where("order_num='{$xml['out_trade_no']}'")->save(array("transaction_id"=>$xml['transaction_id']));
        if($saveorder && $savedetail){
            $addpoints = $this->userpoints(90,$xml['openid'],1,$xml['cash_fee']/100,2,$xml['out_trade_no']);
            $list = M('UserOrderDetail')->where("order_num='{$xml['out_trade_no']}'")->find();
            $return_num = $list['return_num'];
            $totalfee = $list['fee'];
            $dec = M('Event')->where("id={$list['item_id']} and restnums > 0")->setDec('restnums',$list['nums']);
            if(!$dec){
                $this->event_refund($xml,$return_num,$totalfee);
                $this->userpoints(99,$xml['openid'],1,$list['points'],1,$list['order_num']);
                return array("status"=>1);
                exit;
            }
            $event['event_id']=$list['item_id'];//活动ID
            $event['openid']=$xml['openid'];
            $event['name']=$list['name'];
            $event['mobile']=$list['mobile'];
            $event['hospital']=$list['hospital'];
            $event['department']=$list['department'];
            $event['nums']=$list['nums'];
            $add = M('EventRegistration')->add($event);
            if(!$add){
                return array("status"=>0,"msg"=>M('EventRegistration')->getLastSql()); 
            }
            return array("status"=>1);  
        }else{
            return array("status"=>0,"msg"=>M('UserOrder')->getLastSql()); 
        }

    }


    private function event_refund($xml,$return_num,$totalfee){
        $token = M('Token')->where('id=1')->find();
        $param['appid']=C('WX_APPID');//APPID 
        $param['mch_id']=C('WX_MCHID');//商户号
        $param['nonce_str']=$token['noncestr'];//随机数
        $param['transaction_id']=$xml['transaction_id'];//微信订单号
        $param['out_trade_no']=$xml['out_trade_no'];//商户系统内部的订单号
        $param['out_refund_no']=$return_num;
        $param['total_fee']=$totalfee;//
        $param['refund_fee']=$totalfee;
        $param['op_user_id']=C('WX_MCHID');
        $param['sign'] = $this->wxpaySign($param);//支付签名
        $data = $this->wxRefundXML($param);
        if($response = $this->postXmlCurl($data)){
            $xml = (array) simplexml_load_string($response,'SimpleXMLElement', LIBXML_NOCDATA);//XML转数组，还要再验证一次签名
            if( ($xml['return_code']=="SUCCESS") && ($xml['result_code']=="SUCCESS")){
                $wxPrepaySign = $xml['sign'];
                //去除返回的签名
                unset($xml['sign']);
                //
                if($wxPrepaySign==$this->wxpaySign($xml)){
                    $data['refund_id']=$xml['refund_id'];
                    $data['returntime']=time();
                    $data['status']=3;
                    M('UserOrderDetail')->where("order_num='{$return_num}'")->save($data);
                    return 1;
                }else{
                    return 0;
                }
            }elseif($xml['err_code']=='SYSTEMERROR'){//微信支付其实也会抽风的
                $this->event_refund($xml,$return_num,$totalfee);
            }else{
                return 0 ;
            }        
        }else{
            return 0;
        }


    }

    private function wxRefundXML($params){
        $xml="<xml>";
        foreach ($params as $key => $value) {
            $xml .= "<{$key}>$value</{$key}>";
        }
        $xml .="</xml>";
        return $xml;
    }

    private function wxpaySign($param){//微信支付签名（微信支付需要用到3次该方法）
        ksort($param,SORT_STRING);
        foreach ($param as $key => $value) {
            $stringA[]="{$key}={$value}";
        }
        $stringA=implode("&",$stringA);
        $key=C('WX_APIKEY');
        $stringSignTemp="{$stringA}&key={$key}";
        $paySign = strtoupper(md5($stringSignTemp));
        return $paySign;

    }
    private function postXmlCurl($xml,$second = 30)
    {      
        $url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
        //初始化curl        
        $ch = curl_init();
        //设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,TRUE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,TRUE);
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

        curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
        curl_setopt($ch,CURLOPT_SSLCERT, "./notify/apiclient_cert.pem");
        curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
        curl_setopt($ch,CURLOPT_SSLKEY, "./notify/apiclient_key.pem");

        //post提交方式
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        //运行curl
        $data = curl_exec($ch);
        //返回结果
        if($data){
            curl_close($ch);
            return $data;
        }else{
            return 0;
        }
    }

    private function pointsorder($xml){//6金豆
        $condition['order_num']=$xml['out_trade_no'];
        $condition['openid']=$xml['openid'];
        $condition['paytime']=array('eq','');
        $data['transaction_id']=$xml['transaction_id'];
        $data['status']=2;//支付成功;
        $data['paytime']=time();
        $saveorder = M('UserOrder')->where($condition)->save($data);
        $savedetail = M('UserOrderDetail')->where("order_num='{$xml['out_trade_no']}'")->save(array("transaction_id"=>$xml['transaction_id']));
        if($saveorder && $savedetail){
            //购买金豆赠送8
            $addpoints = $this->userpoints(8,$xml['openid'],1,$xml['cash_fee']/100,1,$xml['out_trade_no']);//$type,$openid,$add,$points=0,$is_frozen,$order_num=0
            //充值增加金豆9金豆
            $addpoints = $this->userpoints(9,$xml['openid'],1,$xml['cash_fee'],1,$xml['out_trade_no']);//$type,$openid,$add,$points=0,$is_frozen,$order_num=0
            return array("status"=>1);
            //
        }else{
            return array("status"=>0,"msg"=>M('UserOrder')->getLastSql());
        }        
    }

    /**
     * @param type 金豆规则中的类型ID
     * @param openid 当前用户的微信ID
     * @param add 1标示为增加金豆2标示为减少金豆
     * @param points 手动金豆数
     * @param is_frozen 是否冻结金豆
     * @param order_num 订单号
     */
    private function userpoints($type,$openid,$add,$points=0,$is_frozen,$order_num=0){
        $is_frozen = 1; // 强制去掉冻结状态
        $data['openid']=$openid;
        if(!$points){
            $data['points'] = M('UserPointsRule')->where("id={$type}")->getField('points');//获得金豆规则对应的金豆 
        }else{
            $data['points'] = $points;
        }
        $data['is_frozen']=$is_frozen;
        $data['order_num']=$order_num;
        $data['type']=$type;
        $points = M('UserPoints')->add($data);//插入金豆详细
        if(($add==1) && ($is_frozen==1)){//金豆不冻结
            M('User')->where("openid='{$openid}'")->setInc('points',$data['points']);//更新用户全局金豆
            return 1;
        }elseif(($add!=1)){
            $isDec = M('User')->where("openid='{$openid}' AND points > 0")->setDec('points',$data['points']);
            if(!$isDec){//错误或者没有扣除成功（没有影响到行变化）
                return 0;
            }else{
                return 1;
            }
        }
    }

	private function recevieSuccess(){
		$data="
            <xml>
                <return_code><![CDATA[SUCCESS]]></return_code>
                <return_msg><![CDATA[OK]]></return_msg>
            </xml>
            ";
	  echo $data;
	}
}